
cmake_minimum_required(VERSION 2.8)
cmake_policy(SET CMP0074 NEW)

# Specify default build type if none provided (before project() command)
if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build (Debug or Release)" FORCE)
endif()

# For generators with multiple configurations (like VS), only allow Debug and Release
if(CMAKE_CONFIGURATION_TYPES)
    set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Limited configurations" FORCE)
    mark_as_advanced(CMAKE_CONFIGURATION_TYPES)
endif()

# Project name
project(bomberman)

# Configuration options
set(SFML_STATIC_LIBRARIES FALSE CACHE BOOL "Use static SFML librares")

# General compiler options
if (SFML_STATIC_LIBRARIES)
    add_definitions(-DSFML_STATIC)
endif()

# Specific compiler options - set C++14 flag for g++ and clang
if(CMAKE_COMPILER_IS_GNUCXX)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -pthread -finput-charset=gbk")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -pthread -finput-charset=gbk")
    
    # Mac OS X: clang uses libc++ standard library
    if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
    endif()
endif()

#####################################################################################################################################


# Add directory containing FindSFML.cmake to module path
set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMake/;${CMAKE_MODULE_PATH}")

# Find SFML
# Note: SFML_STATIC_LIBRARIES determines which libraries are found by find_package()
find_package(SFML 2 COMPONENTS audio graphics window system network)

# If found, include and link; otherwise output error message
if(SFML_FOUND)
    include_directories(${SFML_INCLUDE_DIR})
else()
    set(SFML_ROOT "" CACHE PATH "SFML top-level directory")
    message("\n-> SFML directory not found. Set SFML_ROOT to SFML's top-level path (containing \"include\" and \"lib\" directories).")
    message("-> Make sure the SFML libraries with the same configuration (Release/Debug, Static/Dynamic) exist.\n")
endif()

######################################################################################################################################

# Find TGUI
# Note: TGUI_SHARED_LIBS  determines which libraries are found by find_package()
find_package(TGUI 0.9 REQUIRED)

# If found, include and link; otherwise output error message
if(TGUI_FOUND)
    include_directories(${TGUI_INCLUDE_DIR})
else()
    set(TGUI_ROOT "" CACHE PATH "TGUI top-level directory")
    message("\n-> TGUI directory not found. Set TGUI_ROOT to TGUI's top-level path (containing \"include\" and \"lib\" directories).")
    message("-> Make sure the TGUI libraries with the same configuration (Release/Debug, Static/Dynamic) exist.\n")
endif()

######################################################################################################################################


# Find MySQL
# Note: TGUI_SHARED_LIBS  determines which libraries are found by find_package()
find_package(MySQL MODULE REQUIRED)

######################################################################################################################################

# Interprets an argument list separated with keywords.
# Example: 
#  parse_argument_list("MY" "FIRST;SECOND" "FIRST;a;b;c;SECOND;x;y") defines the following variables:
#  MY_FIRST  = a;b;c
#  MY_SECOND = x;y
macro(parse_argument_list PREFIX KEYWORDS ARGUMENTS)
    # Indirection over KEYWORD_LIST necessary because macro parameters are no real variables.
    set(KEYWORD_LIST "${KEYWORDS}")
    set(CURRENT_KEYWORD "")

    # Parse argument list
    foreach(ARG ${ARGUMENTS})
        # See if current argument is in the list of keywords
        list(FIND KEYWORD_LIST "${ARG}" KEYWORD_FOUND)
        if(NOT KEYWORD_FOUND EQUAL -1)
            # If current element is a keyword, store it
            set(CURRENT_KEYWORD ${ARG})
        else()
            # Append current argument to last stored keyword variable
            set(${PREFIX}_${CURRENT_KEYWORD} ${${PREFIX}_${CURRENT_KEYWORD}};${ARG})
        endif()
    endforeach()
endmacro()

######################################################################################################################################

# Macro for client building
# Usage:
#  build_client(Audio SOURCES First.cpp Second.cpp)
macro(build_client CLIENT_NAME)

    # Parse additional arguments (fills variables CLIENT_SOURCES and CLIENT_DEPENDS)
    parse_argument_list("CLIENT" "SOURCES" "${ARGN}")

    # Status output
    message(STATUS "-> Client ${CLIENT_NAME}")


    #############################################################################
    # Build executable
    project(${CLIENT_NAME})

    set(CLIENT_DIR "${PROJECT_SOURCE_DIR}/..")

    # Executable: Add only Main.cpp, set name without _EXE postfix
    add_executable(${PROJECT_NAME} main.cpp ${CLIENT_SOURCES})
    set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME ${CLIENT_NAME})

    # Build static or shared libraries? Set client-specific DLL import macro
    if(SFML_STATIC_LIBRARIES)
        set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_DEFINITIONS "SFML_STATIC")
    endif()

    # Apply the TGUI_USE_STATIC_STD_LIBS option on windows when using VC++
    # This can't be done in the tgui_set_stdlib macro because it is too late to change these variables by then
    if(TGUI_USE_STATIC_STD_LIBS AND (TGUI_COMPILER_MSVC OR (TGUI_OS_WINDOWS AND TGUI_COMPILER_CLANG AND NOT MINGW)))
        foreach(flag
                CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
                CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
            if(${flag} MATCHES "/MD")
                string(REGEX REPLACE "/MD" "/MT" ${flag} "${${flag}}")
            endif()
        endforeach()
    endif()

    # Link SFML. For versions < 2.2, SFML_DEPENDENCIES is not defined, and we do not need to link dependencies
    if(SFML_VERSION_MINOR LESS 2)
        set(SFML_DEPENDENCIES "")
    endif()
    target_link_libraries(${PROJECT_NAME} ${SFML_LIBRARIES} ${SFML_DEPENDENCIES} ${TGUI_LIBRARY} ${MYSQL_LIB})

    install(TARGETS ${PROJECT_NAME}	RUNTIME DESTINATION ${CLIENT_NAME})

    install(DIRECTORY ${CLIENT_DIR}/resources
            DESTINATION ${PROJECT_NAME}
            PATTERN "CMakeLists.txt" EXCLUDE)
    if (WIN32)
        install(DIRECTORY ${SFML_ROOT}/bin/
                DESTINATION ${PROJECT_NAME}
                PATTERN "CMakeLists.txt" EXCLUDE)

        install(DIRECTORY ${TGUI_DIR}/bin/
                DESTINATION ${PROJECT_NAME}
                PATTERN "CMakeLists.txt" EXCLUDE)

        install(FILES ${MYSQL_LIB_DIR}/libmysql.dll
                FILES ${MYSQL_LIB_DIR}/../bin/libssl-1_1-x64.dll
                FILES ${MYSQL_LIB_DIR}/../bin/libcrypto-1_1-x64.dll
                DESTINATION ${PROJECT_NAME})
    endif()
endmacro()

# C++ source code, list of all subdirectories
# Must appear after macros, otherwise they are not visible in subdirectories

add_subdirectory(Client/source)